<{extend name="Public:public0" /}>

<{block name="title"}>安装 与 介绍<{/block}>

<{block name="sidebar"}><{include file="Public:sidebar-vuecli" /}><{/block}>

<{block name="head"}>
	<link rel="stylesheet" type="text/css" href="__ROOT__/css/vuex.css"/>
	<script type="text/javascript" src="__ROOT__/js/vue.js"></script>
<{/block}>


<{block name="content"}>
<div class="content guide with-sidebar components-guide">
<h1>安装 与 介绍</h1>	

<h2 id="installation">
	<a href="#installation" class="headerlink" title="installation" data-scroll="">安装</a>
</h2>	

<h3 id="直接下载-cdn-引用">
	<a href="#直接下载-cdn-引用" aria-hidden="true" class="header-anchor"> 直接下载 / CDN 引用 </a>
</h3>
<p><a href="https://unpkg.com/vuex" target="_blank" rel="noopener noreferrer">https://unpkg.com/vuex<svg xmlns="http://www.w3.org/2000/svg"
		 aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound">
			<path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path>
			<polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon>
		</svg></a></p>
<p><a href="https://unpkg.com" target="_blank" rel="noopener noreferrer">Unpkg.com<svg xmlns="http://www.w3.org/2000/svg"
		 aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound">
			<path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path>
			<polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon>
		</svg></a> 提供了基于 NPM 的 CDN 链接。以上的链接会一直指向 NPM 上发布的最新版本。您也可以通过 <code>https://unpkg.com/vuex@2.0.0</code> 这样的方式指定特定的版本。
</p>
<p>在 Vue 之后引入 <code>vuex</code> 会进行自动安装：</p>
<div class="language-html extra-class">
	<pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>/path/to/vue.js<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token script language-javascript"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>/path/to/vuex.js<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token script language-javascript"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
	</code></pre>
</div>

<h3 id="npm">
	<a href="#npm" aria-hidden="true" class="header-anchor">NPM</a>
</h3>
<div class="language-bash extra-class">
	<pre class="language-bash"><code><span class="token function">npm</span> <span class="token function">install</span> vuex --save
	</code></pre>
</div>
<h3 id="yarn">
	<a href="#yarn" aria-hidden="true" class="header-anchor">Yarn</a>
</h3>
<div class="language-bash extra-class">
	<pre class="language-bash"><code>yarn add vuex
	</code></pre>
</div>
<p>在一个模块化的打包系统中，您必须显式地通过 <code>Vue.use()</code> 来安装 Vuex：</p>
<div class="language-js extra-class">
	<pre class="language-js"><code><span class="token keyword">import</span> Vue <span class="token keyword">from</span> <span class="token string">'vue'</span>
<span class="token keyword">import</span> Vuex <span class="token keyword">from</span> <span class="token string">'vuex'</span>

Vue<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span>Vuex<span class="token punctuation">)</span>
	</code></pre>
</div>
<p>当使用全局 script 标签引用 Vuex 时，不需要以上安装过程。</p>

<h3 id="promise">
	<a href="#promise" aria-hidden="true" class="header-anchor">Promise</a>
</h3>
<p>Vuex 依赖 <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Using_promises" target="_blank" rel="noopener noreferrer">Promise<svg
		 xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"
		 class="icon outbound">
			<path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path>
			<polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon>
		</svg></a>。如果你支持的浏览器并没有实现 Promise (比如 IE)，那么你可以使用一个 polyfill 的库，例如 <a href="https://github.com/stefanpenner/es6-promise"
	 target="_blank" rel="noopener noreferrer">es6-promise<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px"
		 y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound">
			<path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path>
			<polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon>
		</svg></a>。</p>
<p>你可以通过 CDN 将其引入：</p>
<div class="language-html extra-class">
	<pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.js<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token script language-javascript"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
</code></pre>
</div>
<p>然后 <code>window.Promise</code> 会自动可用。</p>
<p>如果你喜欢使用诸如 npm 或 Yarn 等包管理器，可以按照下列方式执行安装：</p>
<div class="language-bash extra-class">
	<pre class="language-bash"><code><span class="token function">npm</span> <span class="token function">install</span> es6-promise --save <span class="token comment"># npm</span>
yarn add es6-promise <span class="token comment"># Yarn</span>
	</code></pre>
</div>
<p>或者更进一步，将下列代码添加到你使用 Vuex 之前的一个地方：</p>
<div class="language-js extra-class">
	<pre class="language-js"><code><span class="token keyword">import</span> <span class="token string">'es6-promise/auto'</span>
	</code></pre>
</div>


<h3 id="自己构建">
	<a href="#自己构建" aria-hidden="true" class="header-anchor">自己构建</a> 
</h3>
<p>如果需要使用 dev 分支下的最新版本，您可以直接从 GitHub 上克隆代码并自己构建。</p>
<div class="language-bash extra-class">
	<pre class="language-bash"><code><span class="token function">git</span> clone https://github.com/vuejs/vuex.git node_modules/vuex
<span class="token function">cd</span> node_modules/vuex
<span class="token function">npm</span> <span class="token function">install</span>
<span class="token function">npm</span> run build
	</code></pre>
</div>

<br><br>




<h2 id="introduce">
	<a href="#introduce" class="headerlink" title="introduce" data-scroll="">Vuex 是什么？</a>
</h2>	
<p>Vuex 是一个专为 Vue.js 应用程序开发的<strong>状态管理模式</strong>。它采用集中式存储管理应用的所有组件的状态，并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue
	的官方调试工具 <a href="https://github.com/vuejs/vue-devtools" target="_blank" rel="noopener noreferrer">devtools extension<svg
		 xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"
		 class="icon outbound">
			<path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path>
			<polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon>
		</svg></a>，提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。</p>
<h3 id="什么是“状态管理模式”？">
	<a href="#什么是“状态管理模式”？" aria-hidden="true" class="header-anchor">什么是“状态管理模式”？</a> 
</h3>
<p>让我们从一个简单的 Vue 计数应用开始：</p>
<div class="language-js extra-class">
	<pre class="language-js"><code><span class="token keyword">new</span> <span class="token class-name">Vue</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token comment">// state</span>
  <span class="token function">data</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span>
      count<span class="token punctuation">:</span> <span class="token number">0</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  <span class="token comment">// view</span>
  template<span class="token punctuation">:</span> <span class="token template-string"><span class="token string">`
    &lt;div&gt;{{ count }}&lt;/div&gt;
  `</span></span><span class="token punctuation">,</span>
  <span class="token comment">// actions</span>
  methods<span class="token punctuation">:</span> <span class="token punctuation">{</span>
    <span class="token function">increment</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span>count<span class="token operator">++</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre>
</div>
<p>这个状态自管理应用包含以下几个部分：</p>
<ul>
	<li><strong>state</strong>，驱动应用的数据源；</li>
	<li><strong>view</strong>，以声明方式将 <strong>state</strong> 映射到视图；</li>
	<li><strong>actions</strong>，响应在 <strong>view</strong> 上的用户输入导致的状态变化。</li>
</ul>
<p>以下是一个表示“单向数据流”理念的极简示意：</p>
<p style="text-align: center; margin: 2em;"><img src="__ROOT__/images/vuex/flow.png" style="width: 100%; max-width: 450px;"></p>
<p>但是，当我们的应用遇到<strong>多个组件共享状态</strong>时，单向数据流的简洁性很容易被破坏：</p>
<ul>
	<li>多个视图依赖于同一状态。</li>
	<li>来自不同视图的行为需要变更同一状态。</li>
</ul>
<p>对于问题一，传参的方法对于多层嵌套的组件将会非常繁琐，并且对于兄弟组件间的状态传递无能为力。对于问题二，我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱，通常会导致无法维护的代码。</p>
<p>因此，我们为什么不把组件的共享状态抽取出来，以一个全局单例模式管理呢？在这种模式下，我们的组件树构成了一个巨大的“视图”，不管在树的哪个位置，任何组件都能获取状态或者触发行为！</p>
<p>另外，通过定义和隔离状态管理中的各种概念并强制遵守一定的规则，我们的代码将会变得更结构化且易维护。</p>
<p>这就是 Vuex 背后的基本思想，借鉴了 <a href="https://facebook.github.io/flux/docs/overview.html" target="_blank" rel="noopener noreferrer">Flux<svg
		 xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15"
		 class="icon outbound">
			<path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path>
			<polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon>
		</svg></a>、<a href="http://redux.js.org/" target="_blank" rel="noopener noreferrer">Redux<svg xmlns="http://www.w3.org/2000/svg"
		 aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound">
			<path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path>
			<polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon>
		</svg></a>、和 <a href="https://guide.elm-lang.org/architecture/" target="_blank" rel="noopener noreferrer">The Elm
		Architecture<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15"
		 height="15" class="icon outbound">
			<path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path>
			<polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon>
		</svg></a>。与其他模式不同的是，Vuex 是专门为 Vue.js 设计的状态管理库，以利用 Vue.js 的细粒度数据响应机制来进行高效的状态更新。</p>
<p><img src="__ROOT__/images/vuex/vuex.png" alt="vuex"></p>


<h3 id="什么情况下我应该使用-vuex？">
	<a href="#什么情况下我应该使用-vuex？" aria-hidden="true" class="header-anchor">什么情况下我应该使用 Vuex？</a> 
</h3>
<p>虽然 Vuex 可以帮助我们管理共享状态，但也附带了更多的概念和框架。这需要对短期和长期效益进行权衡。</p>
<p>如果您不打算开发大型单页应用，使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单，您最好不要使用 Vuex。一个简单的 <a href="https://cn.vuejs.org/v2/guide/state-management.html#%E7%AE%80%E5%8D%95%E7%8A%B6%E6%80%81%E7%AE%A1%E7%90%86%E8%B5%B7%E6%AD%A5%E4%BD%BF%E7%94%A8"
	 target="_blank" rel="noopener noreferrer">store 模式<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px"
		 y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound">
			<path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path>
			<polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon>
		</svg></a>就足够您所需了。但是，如果您需要构建一个中大型单页应用，您很可能会考虑如何更好地在组件外部管理状态，Vuex 将会成为自然而然的选择。引用 Redux 的作者 Dan Abramov 的话说就是：</p>
<blockquote>
	<p>Flux 架构就像眼镜：您自会知道什么时候需要它。</p>
</blockquote>
	
<br><br>






<h2 id="guide0">
	<a href="#guide0" class="headerlink" title="guide0" data-scroll="">开始</a>
</h2>	
<p>每一个 Vuex 应用的核心就是 store（仓库）。“store”基本上就是一个容器，它包含着你的应用中大部分的<strong>状态 (state)</strong>。Vuex 和单纯的全局对象有以下两点不同：</p>
<ol>
	<li>
		<p>Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候，若 store 中的状态发生变化，那么相应的组件也会相应地得到高效更新。</p>
	</li>
	<li>
		<p>你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地<strong>提交 (commit) mutation</strong>。这样使得我们可以方便地跟踪每一个状态的变化，从而让我们能够实现一些工具帮助我们更好地了解我们的应用。</p>
	</li>
</ol>


<h3 id="最简单的-store">
	<a href="#最简单的-store" aria-hidden="true" class="header-anchor">最简单的 Store</a> 
</h3>
<blockquote>
	<p><strong>提示：</strong> 我们将在后续的文档示例代码中使用 ES2015 语法。如果你还没能掌握 ES2015，<a href="https://babeljs.io/docs/learn-es2015/"
		 target="_blank" rel="noopener noreferrer">你得抓紧了<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px"
			 viewBox="0 0 100 100" width="15" height="15" class="icon outbound">
				<path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path>
				<polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon>
			</svg></a>！</p>
</blockquote>
<p><a href="/zh/installation.html" class="">安装</a> Vuex 之后，让我们来创建一个 store。创建过程直截了当——仅需要提供一个初始 state 对象和一些 mutation：</p>
<div class="language-js extra-class">
	<pre class="language-js"><code><span class="token comment">// 如果在模块化构建系统中，请确保在开头调用了 Vue.use(Vuex)</span>

<span class="token keyword">const</span> store <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Vuex<span class="token punctuation">.</span>Store</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  state<span class="token punctuation">:</span> <span class="token punctuation">{</span>
    count<span class="token punctuation">:</span> <span class="token number">0</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
  mutations<span class="token punctuation">:</span> <span class="token punctuation">{</span>
    <span class="token function">increment</span> <span class="token punctuation">(</span>state<span class="token punctuation">)</span> <span class="token punctuation">{</span>
      state<span class="token punctuation">.</span>count<span class="token operator">++</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre>
</div>
<p>现在，你可以通过 <code>store.state</code> 来获取状态对象，以及通过 <code>store.commit</code> 方法触发状态变更：</p>
<div class="language-js extra-class">
	<pre class="language-js"><code>store<span class="token punctuation">.</span><span class="token function">commit</span><span class="token punctuation">(</span><span class="token string">'increment'</span><span class="token punctuation">)</span>

console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>store<span class="token punctuation">.</span>state<span class="token punctuation">.</span>count<span class="token punctuation">)</span> <span class="token comment">// -&gt; 1</span>
</code></pre>
</div>
<p>再次强调，我们通过提交 mutation 的方式，而非直接改变 <code>store.state.count</code>，是因为我们想要更明确地追踪到状态的变化。这个简单的约定能够让你的意图更加明显，这样你在阅读代码的时候能更容易地解读应用内部的状态改变。此外，这样也让我们有机会去实现一些能记录每次状态改变，保存状态快照的调试工具。有了它，我们甚至可以实现如时间穿梭般的调试体验。</p>
<p>由于 store 中的状态是响应式的，在组件中调用 store 中的状态简单到仅需要在计算属性中返回即可。触发变化也仅仅是在组件的 methods 中提交 mutation。</p>
<p>这是一个<a href="https://jsfiddle.net/n9jmu5v7/1269/" target="_blank" rel="noopener noreferrer">最基本的 Vuex 记数应用<svg xmlns="http://www.w3.org/2000/svg"
		 aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound">
			<path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path>
			<polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon>
		</svg></a>示例。</p>
<p>接下来，我们将会更深入地探讨一些核心概念。让我们先从 <a href="/zh/guide/state.html" class="">State</a> 概念开始。</p>
	
	
</div>
<{/block}>
